package com.jmlee.utils;

import com.jmlee.controller.WebSocketServerEndpoint;
import com.jmlee.vo.AddressByOrderVo;
import com.jmlee.vo.AddressByRiderVo;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.operation.buffer.BufferOp;
import com.vividsolutions.jts.algorithm.PointLocator;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author： 郑锦涛
 * @data： 2021/3/14 20:04
 * @version：1.0
 * @描述： 检查经纬度方圆内情况的工具类
 */
public class CheckInCircle {

    private final static double EARTH_RADIUS = 6378.137;//地球半径

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }



    /**
     * 判断经纬度是否在圆内
     * @param lon 目标经度
     * @param lat 目标纬度
     * @param dis 距离，米
     * @param centerLon 圆心经度
     * @param centerLat 圆心纬度
     * @return
     */
    public static boolean inCircle(float lon, float lat,long dis,float centerLon,float centerLat){
        //创建一条直线
        Coordinate[] coordinates4 = new Coordinate[] {
                new Coordinate(centerLon,centerLat),
                new Coordinate(centerLon,centerLon+0.01f*dis/1000),
        };

        GeometryFactory gf=new GeometryFactory();
        Geometry gfLineString = gf.createLineString(coordinates4);
        //将度换算成米，公式为：degree = meter / (2 * Math.PI * 6371004) * 360
        double degree = dis / (2*Math.PI*6371004)*360;
        //缓冲区建立
        BufferOp bufOp = new BufferOp(gfLineString);
        bufOp.setEndCapStyle(BufferOp.CAP_BUTT);
        Geometry bg = bufOp.getResultGeometry(degree);
        //点是否在多边形内判断
        Coordinate point = new Coordinate(lon,lat);
        PointLocator a=new PointLocator();
        boolean p1=a.intersects(point, bg);
        if(p1) {
            System.out.println("point1:" + "该点在多边形内" + p1);
        }else {
            System.out.println("point1:" + "该点不在多边形内" + p1);
        }
        return p1;
    }

    /**
     * 计算国内坐标系两点间距离 （高德地图）
     * lat1     目标纬度
     * lng1     目标经度
     *
     * @return double 距离 单位公里,精确到米
     */
    public static double GetDistance(double lng1, double lat1, double lng2, double lat2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = new BigDecimal(s).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
        return s;
    }

    /**
     * 获取骑手方圆5公里内的订单
     * @param list              订单
     * @param addressByRiderVo  骑手位置信息
     * @return                  骑手方圆5公里内的订单
     */
    public static List<AddressByOrderVo> inCircleOrders(List<AddressByOrderVo> list, AddressByRiderVo addressByRiderVo){
        //判断是否有订单
        if (list.size() > 0){
            //判断是否有骑手的位置坐标
            //骑手坐标不为空
            if (addressByRiderVo != null){
                for (int i = 0 ;i<=list.size();i++){
                    //判断商家坐标与用户坐标是否在骑手方圆5公里内，如果不在，则移除订单信息
                    if (
                        !inCircle(
                            list.get(i).getShopLongitude(),
                            list.get(i).getShopLatitude(),
                            10000,
                            addressByRiderVo.getRiderLongitude(),
                            addressByRiderVo.getRiderLatitude())
                                ||
                        !inCircle(
                            list.get(i).getUserLongitude(),
                            list.get(i).getUserLatitude(),
                            10000,
                            addressByRiderVo.getRiderLongitude(),
                            addressByRiderVo.getRiderLatitude())
                    ){
                        //移除动作
                        list.remove(i);
                    }
                }
            }
            //骑手坐标为空
            if (WebSocketServerEndpoint.addressByRiderVo == null){
                //清空list集合
                list= null;
            }
        }
        return list;
    }


    public static List<AddressByOrderVo> inCircleOrder(List<AddressByOrderVo> list, AddressByRiderVo addressByRiderVo){
        Integer distance = 10000;
        //判断是否有订单
        if (list.size() > 0){
            //判断是否有骑手的位置坐标
            //骑手坐标不为空
            if (addressByRiderVo != null){
                for (int i = 0 ;i<list.size();i++){
                    //判断商家坐标与用户坐标是否在骑手方圆5公里内，如果不在，则移除订单信息
                    if (
                        GetDistance(list.get(i).getShopLongitude(),
                                list.get(i).getShopLatitude(),
                                addressByRiderVo.getRiderLongitude(),
                                addressByRiderVo.getRiderLatitude())>=distance
                            ||
                        GetDistance(list.get(i).getUserLongitude(),
                                list.get(i).getUserLatitude(),
                                addressByRiderVo.getRiderLongitude(),
                                addressByRiderVo.getRiderLatitude())>=distance
                    ){
                        //移除动作
                        list.remove(i);
                    }
                }
            }
            //骑手坐标为空
            if (WebSocketServerEndpoint.addressByRiderVo == null){
                //清空list集合
                list= null;
            }
        }
        return list;
    }



}
